#include <string.h> // 包含定义 strlen 函数的头文件
#include "net.h"
#include "util.h"

/*debug printf*/
#define TAG_NET                        "NET"
#define DebugPrint_Net(fmt,...)         printWithTimestamp(TAG_NET,DEBUG_LEVEL_INFO, fmt, ##__VA_ARGS__) // 带时间戳
#define DebugPrint_Net_DEG(fmt,...)    printWithTimestamp(TAG_NET,DEBUG_LEVEL_DEBUG, fmt, ##__VA_ARGS__) // 带时间戳


/*
 * delayConfig初始化数组，包含4个延迟配置：
 * 专门为测试设计，模拟模块内部运行流程。
 * 
 *   - type: 配置类型
 *   - data: 延迟时间（毫秒）
 */
static DelayConfig delayConfig[] = {
    {(uint8_t)NET_MSG_CONNECTING, {5000}}, // 初始化type为0，data数组的第一个元素为1000
    {(uint8_t)NET_MSG_CONNECT_TIMEOUT, {10000}}, // 初始化type为1，data数组的第一个元素为2000
    // {2, {3000}}, // 初始化type为2，data数组的第一个元素为3000
    // {3, {4000}}  // 初始化type为3，data数组的第一个元素为4000
};


// 网络事件处理任务
NetEvent netEvent;

// 网络状态报告
static NetReport netReport = {0};


// 网络事件队列
static QueueHandle_t xNetEventQueue = NULL;

// 申明 Net_EventLoopTask函数
void Net_EventLoopTask(void* arg);
void Net_Handle(NetEvent* event);

// 网络初始化
void Net_Init(void) {

    // 打印函数名
    DebugPrint_Net("Net_Init");

    // 初始化网络硬件或软件
    
    // 创建 xNetEventQueue 队列
    xNetEventQueue = xQueueCreate(10, sizeof(NetEvent));

    // 检查队列创建是否成功
    if (xNetEventQueue == NULL) {
        // 处理错误：队列创建失败
        DebugPrint_Net("xQueueCreate failed");
    }

    // 创建 Net_EventLoopTask 任务
    if (xTaskCreate(Net_EventLoopTask, "NetEventLoop", 1024, NULL, 2, NULL) != pdTRUE) {
        // 处理错误：任务创建失败
    }

	// 初始化网络状态
	NetEvent next_event;
	next_event.type = NET_EVENT_INIT;
	next_event.message = "123456789"; // 类型测试
	Net_Handle(&next_event);

}

// 网络反初始化
void Net_Deinit(void) {
    // 反初始化网络硬件或软件
    // vQueueDelete(xNetEventQueue);
}

// 网络事件循环任务
void Net_EventLoopTask(void* arg) {
    NetEvent event,next_event;
	uint32_t delay = 0;
    while (1) {
        if (xQueueReceive(xNetEventQueue, &event, portMAX_DELAY) == pdTRUE) {
            // 根据事件类型调用用户回调接口
			// 打印调试信息，显示处理的事件类型
			vTaskDelay(10 / portTICK_PERIOD_MS);
			DebugPrint_Net(" recv event.type=%d\r\n", event.type);
			DebugPrint_Net(" recv event.message not NULL: %d\r\n", 
							event.message==NULL?pdFALSE:pdTRUE);	
			if(event.message != NULL){
				if(sizeof(event.message) == sizeof(uint16_t)){
					DebugPrint_Net(" recv event.message=%d\r\n", (uint16_t*)event.message);
				}else{
					DebugPrint_Net(" recv event.message=%s len=%d\r\n", 
									(char*)event.message, 
									strlen((char*)event.message));
				}
			}
            switch (event.type) {
				case NET_EVENT_INIT:
					// 初始化事件处理
					netReport.netState = NET_STATE_INITIALIZED;
					netReport.netMsgType = NET_MSG_INITIALIZED;
					break;
                case NET_EVENT_CONNECTING:
                    // 连接事件处理
					netReport.netState = NET_STATE_CONNECTING;
					netReport.netMsgType = NET_MSG_CONNECTING;
					if(event.message != NULL){
						delay = GetDelayDuration((uint8_t)NET_MSG_CONNECT_TIMEOUT,
												delayConfig,
												sizeof(delayConfig) / sizeof(delayConfig[0]));
						DebugPrint_Net("connect timeout message=%d delay=%d\r\n", (uint16_t*)event.message, delay);
						next_event.type = NET_EVENT_CONNECT_TIMEOUT;
						next_event.message = NULL;
						Net_Handle(&next_event);

					}else{
						delay = GetDelayDuration((uint8_t)NET_MSG_CONNECTING,
												delayConfig,
												sizeof
												(delayConfig) / sizeof(delayConfig[0]));
					    DebugPrint_Net("connecting delay=%d \r\n", delay);
						next_event.type = NET_EVENT_CONNECTED;
						next_event.message = NULL;
						Net_Handle(&next_event);
					}
					vTaskDelay(delay);

                    break;
				case NET_EVENT_CONNECTED:
					netReport.netState = NET_STATE_CONNECTED;
					netReport.netMsgType = NET_MSG_CONNECTED;

					break;
                case NET_EVENT_CONNECT_TIMEOUT:
                    // 断开事件处理
					netReport.netState = NET_STATE_DISCONNECTED;	
					netReport.netMsgType = NET_MSG_CONNECT_TIMEOUT;
                    break;
				default:
					break;
            }
			if(net.userEventHook != NULL){
				net.userEventHook(&event, &netReport);
			}
        }
    }
}

// 获取网络状态报告
uint8_t Net_GetReport(NetReport *report) {
	//  把netReport复制到report指向的NetReport结构体中
	*report = netReport;

	if (report == NULL) {
        return pdFALSE; // 返回错误码，例如：无效参数
    }
    
    // 将当前网络状态和消息类型复制到传出参数 report 中
    *report = netReport;
    
    // 返回状态码，例如：成功返回 1
    return pdTRUE;
}

/**
 * 处理网络事件。
 * 
 * @param eventType 事件类型，决定如何处理网络事件。
 * @param report 指向NetReport结构体的指针，包含事件相关的详细报告。本函数中未使用该参数。
 */
void Net_Handle(NetEvent *event) {
	// 创建一个NetEventType结构体实例，用于存储接收到的事件类型
	NetEvent netEvent = *event;
	
	// 打印调试信息，显示处理的事件类型
	DebugPrint_Net(" handle event addr=%p\r\n", event);
	DebugPrint_Net(" handle netEvent addr=%p\r\n", &netEvent);
	DebugPrint_Net(" handle event.type=%d\r\n", event->type);
	DebugPrint_Net(" handle event.message not NULL: %d\r\n", 
						event->message==NULL?pdFALSE:pdTRUE);
	
    // 将事件发送到xNetEventQueue队列，使用阻塞方式，等待时间设为portMAX_DELAY
    xQueueSend(xNetEventQueue, &netEvent, portMAX_DELAY);

}


// 网络模块实例化
NetModule net = {
    .Init = Net_Init,
    .Deinit = Net_Deinit,
    // .EventLoopTask = Net_EventLoopTask,
    .GetReport = Net_GetReport,
    .Handle = Net_Handle,
	.userEventHook = NULL
};

// 其他辅助函数...
